sentence is truncated - and missing part of the line, including the checksum.
*/
-struct NmeaWaypoint : Waypoint
-{
- bool added{false};
-};
-
enum preferred_posn_type {
gp_unknown = 0,
gpgga,
static short_handle mkshort_handle;
static preferred_posn_type posn_type;
static struct tm tm;
-static NmeaWaypoint* curr_waypt;
-static NmeaWaypoint* last_waypt;
+static Waypoint* curr_waypt;
+static Waypoint* last_waypt;
static void* gbser_handle;
static QString posn_fname;
-static QList<NmeaWaypoint*> pcmpt_head;
+static QList<Waypoint*> pcmpt_head;
static int without_date; /* number of created trackpoints without a valid date */
static struct tm opt_tm; /* converted "date" parameter */
static long sleepus;
static int getposn;
static int append_output;
-static int amod_waypoint;
+static bool amod_waypoint;
static time_t last_time;
static double last_read_time; /* Last timestamp of GGA or PRMC */
static Waypoint* nmea_rd_posn(posn_status*);
static void nmea_rd_posn_init(const QString& fname);
+static int wpt_not_added_yet;
+
static QVector<arglist_t> nmea_args = {
{"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64", nullptr },
{"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
return x;
}
+static Waypoint*
+nmea_new_wpt()
+{
+ auto* wpt = new Waypoint();
+ // Set extra data to something other than nullptr to indicate to
+ // nmea_release_wpt that ownership of the waypoint is our
+ // repsonsibility.
+ wpt->extra_data = &wpt_not_added_yet;
+ return wpt;
+}
+
static void
-nmea_add_base_wpt(Waypoint* wpt, route_head* trk)
+nmea_add_wpt(Waypoint* wpt, route_head* trk)
{
+ // Reset extra data.
+ // This also indicates to nmea_release_wpt that ownership has been
+ // transferred to either the global_waypoint_list or global_track_list.
+ wpt->extra_data = nullptr;
if (datum != DATUM_WGS84) {
double lat, lon, alt;
GPS_Math_Known_Datum_To_WGS84_M(
}
static void
-nmea_add_wpt(NmeaWaypoint* wpt, route_head* trk)
-{
- wpt->added = true;
- nmea_add_base_wpt(wpt, trk);
-}
-
-static void
-nmea_release_wpt(NmeaWaypoint* wpt)
+nmea_release_wpt(Waypoint* wpt)
{
- if (wpt && !wpt->added) {
- /* This waypoint isn't queued.
- Release it, because we don't have any reference to this
- waypoint (! memory leak !) */
+ if (wpt && (wpt->extra_data != nullptr)) {
+ // Ownership of this waypoint hasn't been transferred to a global
+ // list, so we must delete it to avoid a memory leak.
delete wpt;
}
}
if (getposn) {
posn_status st;
nmea_rd_posn_init(fname);
- auto wpt = nmea_rd_posn(&st);
+ Waypoint* wpt = nmea_rd_posn(&st);
if (!wpt) {
return;
}
wpt->shortname = "Position";
- nmea_add_base_wpt(wpt, nullptr);
+ nmea_add_wpt(wpt, nullptr);
return;
}
hms = hms / 100;
tm.tm_hour = hms % 100;
- auto waypt = new NmeaWaypoint;
+ Waypoint* waypt = nmea_new_wpt();
nmea_set_waypoint_time(waypt, &tm, fsec);
hms = hms / 100;
tm.tm_hour = (long) hms % 100;
- auto waypt = new NmeaWaypoint;
+ Waypoint* waypt = nmea_new_wpt();
nmea_set_waypoint_time(waypt, &tm, fsec);
}
/* This point is both a waypoint and a trackpoint. */
if (amod_waypoint) {
- waypt_add(new Waypoint(*curr_waypt));
- amod_waypoint = 0;
+ nmea_add_wpt(new Waypoint(*curr_waypt), nullptr);
+ amod_waypoint = false;
}
return;
}
- auto waypt = new NmeaWaypoint;
+ Waypoint* waypt = nmea_new_wpt();
WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed));
WAYPT_SET(waypt, course, course);
/* This point is both a waypoint and a trackpoint. */
if (amod_waypoint) {
- waypt_add(new Waypoint(*waypt));
- amod_waypoint = 0;
+ nmea_add_wpt(new Waypoint(*waypt), nullptr);
+ amod_waypoint = false;
}
}
lngdeg = -lngdeg;
}
- auto waypt = new NmeaWaypoint;
+ Waypoint* waypt = nmea_new_wpt();
waypt->latitude = ddmm2degrees(latdeg);
waypt->longitude = ddmm2degrees(lngdeg);
waypt->shortname = sname;
}
if (lat || lon) {
- curr_waypt = new NmeaWaypoint;
+ curr_waypt = nmea_new_wpt();
curr_waypt->longitude = pcmpt_deg(lon);
curr_waypt->latitude = pcmpt_deg(lat);
route_head* trk_head = route_head_alloc();
track_add_head(trk_head);
while (!pcmpt_head.isEmpty()) {
- auto wpt = pcmpt_head.takeFirst();
+ Waypoint* wpt = pcmpt_head.takeFirst();
nmea_add_wpt(wpt, trk_head);
}
}
} else if (opt_gpgsa && (0 == notalkerid_strmatch(tbuf, "GSA"))) {
gpgsa_parse(tbuf); /* GPS fix */
} else if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) {
- amod_waypoint = 1;
+ amod_waypoint = true;
}
if (tbuf != ibuf) {
nmea_parse_one_line(ibuf);
if (lt != last_read_time) {
if (last_read_time) {
- auto w = curr_waypt;
+ Waypoint* w = curr_waypt;
lt = last_read_time;
curr_waypt = nullptr;